package com.zzyl.nursing.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.nursing.domain.Reservation;
import com.zzyl.nursing.dto.ReservationDto;
import com.zzyl.nursing.mapper.ReservationMapper;
import com.zzyl.nursing.service.IReservationService;
import com.zzyl.nursing.vo.ReservationCountByTimeVo;
import java.time.LocalDateTime;
import java.util.List;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.VisitRegistration;
import com.zzyl.nursing.mapper.VisitRegistrationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.ReservationMapper;
import com.zzyl.nursing.domain.Reservation;
import com.zzyl.nursing.service.IReservationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
/**
 * 预约信息Service业务层处理
 *
 * @author ruoyi
 * @date 2025-08-28
 */
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

@Service
public class ReservationServiceImpl extends ServiceImpl<ReservationMapper,Reservation> implements IReservationService
{
public class ReservationServiceImpl implements IReservationService{


    @Autowired
    private ReservationMapper reservationMapper;
    @Autowired
    private VisitRegistrationMapper visitRegistrationMapper;
    /**
     * 查询预约信息
     *
     * @param id 预约信息主键
     * @return 预约信息
     */

    @Override
    public Reservation selectReservationById(Long id)
    {
        return getById(id);
    public Long cancelledCount(Long loginUser) {
        //获取用户取消预约数量
        Long count = reservationMapper.cancelledCount(loginUser);
        //当天取消预约次数
        if (count >= 3){
            throw new RuntimeException("当天取消预约次数大于3次，禁止预约");
        }
        return count;
    }

    /**
     * 查询预约信息列表
     *
     * @param reservation 预约信息
     * @return 预约信息
     */
    @Override
    public List<ReservationCountByTimeVo> reservationCountByTime(Long time) {
        // 将时间戳转换为LocalDateTime
        LocalDateTime targetTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());

        // 计算时间范围：目标时间前后1小时
        LocalDateTime startTime = targetTime.minusHours(1);
        LocalDateTime endTime = targetTime.plusHours(1);

        // 获取指定时间段的预约次数
        Long timeCount = reservationMapper.reservationCountByTimeRange(startTime, endTime);

        // 计算剩余预约机会次数（最多6次）
        Long remainingCount = 6 - timeCount;


        // 将获取到的数量封装在ReservationCountByTimeVo中
        ReservationCountByTimeVo reservationCountByTimeVo = new ReservationCountByTimeVo();
        reservationCountByTimeVo.setCount(remainingCount); // 设置剩余次数
        reservationCountByTimeVo.setTime(targetTime);

        // 将ReservationCountByTimeVo对象放入List集合并返回
        List<ReservationCountByTimeVo> result = new ArrayList<>();
        result.add(reservationCountByTimeVo);

        return result;
    public List<Reservation> selectReservationList(Reservation reservation)
    {
        return reservationMapper.selectReservationList(reservation);
    }

    /**
     * 新增预约信息
     *
     * @param reservation 预约信息
     * @return 结果
     */
    @Override
    public int insertReservation(Reservation reservation)
    {
        return save(reservation)?1:0;
    public void add(ReservationDto reservationDto) {

        // 检查预约时间段内的预约次数是否超过6次
        QueryWrapper<Reservation> timeQueryWrapper = new QueryWrapper<>();
        timeQueryWrapper.and(wrapper -> wrapper.eq("status", 0).or().eq("status", 1))
                .between("time",
                        reservationDto.getTime().minusHours(1),
                        reservationDto.getTime().plusHours(1));
        Long timeCount = reservationMapper.selectCount(timeQueryWrapper);
        if (timeCount > 6) {
            throw new BaseException("该时间段预约已满");
        }

        //获取用户手机号
        QueryWrapper<Reservation> phoneQueryWrapper = new QueryWrapper<>();
        phoneQueryWrapper.eq("mobile", reservationDto.getMobile())
                .and(wrapper -> wrapper.eq("status", 0).or().eq("status", 1))
                .between("time",
                        reservationDto.getTime().minusHours(1),
                        reservationDto.getTime().plusHours(1));

        Long phoneCount = reservationMapper.selectCount(phoneQueryWrapper);
        if (  phoneCount>0 ) {
            throw new BaseException("一个手机号只能进行一次预约");
        }






        // 检查同一手机号在当天取消预约的次数是否超过3次
        QueryWrapper<Reservation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", reservationDto.getMobile())
                .eq("status", 2)  // 状态为取消
                .apply("DATE(update_time) = CURDATE()");  // 当天取消

        Long cancelledCount = reservationMapper.selectCount(queryWrapper);
        if (cancelledCount >= 3) {
            throw new RuntimeException("当天取消预约超过三次，禁止预约");
        }

        Reservation reservation = new Reservation();
        // 设置创建人信息
        Long userId = UserThreadLocal.getUserId();
        if (userId != null) {
            reservation.setCreateBy(userId);
        }
        reservation.setName(reservationDto.getName());
        reservation.setMobile(reservationDto.getMobile());
        reservation.setTime(reservationDto.getTime());
        reservation.setType(reservationDto.getType());
        reservation.setVisitor(reservationDto.getVisitor());
        // 设置预约状态
        reservation.setStatus(0);
        // 设置创建时间
        reservation.setCreateTime(LocalDateTime.now());
        reservationMapper.insert(reservation);

    }

    /**
     * 修改预约信息
     *
     * @param reservation 预约信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateReservation(Reservation reservation)
    {
        reservation = reservationMapper.selectById(reservation.getId());
        VisitRegistration visitRegistration = new VisitRegistration();
        visitRegistration.setReservationId(reservation.getId());//预约IDname
        visitRegistration.setVisitorName(reservation.getName());//来访人姓名
       visitRegistration.setVisitorMobile(reservation.getMobile());
        visitRegistration.setElderName(reservation.getVisitor());
        visitRegistration.setVisitTime(LocalDateTime.now());
       visitRegistration.setType(reservation.getType());
        //好了
        visitRegistrationMapper.insert(visitRegistration);//添加来访信息
//没有状态字段
        return updateById(reservation)?1:0;
    public List<Reservation> selectReservationList(Reservation reservation) {
        return reservationMapper.selectReservationList(reservation);
    }

    /**
     * 批量删除预约信息
     *
     * @param ids 需要删除的预约信息主键
     * @return 结果
     */
    @Override
    public void cancelUpdate(Long id) {
        // 获取当前登录的用户信息
        Long userId = UserThreadLocal.getUserId();
        if (userId == null) {
            throw new RuntimeException("用户未登录");
        }

        // 检查预约是否已过期
        Reservation existingReservation = reservationMapper.selectById(id);
        if (existingReservation == null) {
            throw new RuntimeException("预约记录不存在");
        }

        // 如果预约已过期，则不能取消
        if (existingReservation.getStatus() == 3) {
            throw new RuntimeException("预约已过期，无法取消");
        }

        // 创建预约对象并设置状态为取消(2)
        Reservation reservation = new Reservation();
        reservation.setId(id);
        reservation.setStatus(2);
        reservation.setUpdateTime(LocalDateTime.now());
        reservation.setUpdateBy(userId);

        //如果当日用户取消三次预约，则不允许取消预约
        Long cancelledCount = reservationMapper.cancelledCount(userId);
        if (cancelledCount >= 3) {
            throw new RuntimeException("当日用户取消预约次数已超过3次，无法取消预约");
        }

        // 更新预约状态
        reservationMapper.updateById(reservation);
    }



    public int deleteReservationByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids))?1:0;
    }

    /**
     * 删除预约信息信息
     *
     * @param id 预约信息主键
     * @return 结果
     */
    @Override
    public int deleteReservationById(Long id)
    {
        return removeById(id)?1:0;
    }

}
